﻿namespace NuGetCop.MSBuild.Tasks
{
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Globalization;
    using System.Linq;
    using NuGetCop.MSBuild.Tasks.Configuration;
    using NuGetCop.MSBuild.Tasks.Resources;

    internal sealed class NuGetPackageChecker : INuGetPackageChecker
    {
        public INuGetPackageCheckResult CheckNuGetPackageRule(NuGetCopRuleSettings rule, INuGetPackageRepository packageRepository)
        {
            var packageRefereces = packageRepository
                .PackageReferences
                .Where(x => x.Id == rule.PackageId)
                .ToArray();

            var errors = new List<string>();

            switch (packageRefereces.Length)
            {
                case 0:
                    errors.Add(string.Format(
                        CultureInfo.InvariantCulture,
                        Msg.MissedRequiredPackageFormat,
                        rule.PackageId,
                        rule.Version,
                        rule.TargetFramework));

                    break;

                case 1:
                    var packageReference = packageRefereces[0];
                    Contract.Assume(packageReference != null);

                    if (packageReference.Version == rule.Version)
                    {
                        if (packageReference.TargetFramework != rule.TargetFramework)
                        {
                            errors.Add(string.Format(
                                CultureInfo.InvariantCulture,
                                Msg.WrongPackageTargetFrameworkFormat,
                                rule.PackageId,
                                rule.TargetFramework,
                                packageReference.TargetFramework));
                        }
                    }
                    else
                    {
                        errors.Add(string.Format(
                            CultureInfo.InvariantCulture,
                            Msg.WrongPackageVersionFormat,
                            rule.PackageId,
                            rule.Version,
                            packageReference.Version));
                    }
                    break;
                    
                default:
                    errors.Add(string.Format(
                        CultureInfo.InvariantCulture,
                        Msg.MultiplePackageReferencesFormat,
                        rule.PackageId));
                    break;
            }

            return new NuGetPackageCheckResult(packageRefereces, errors);
        }
    }
}